//
// Created by chao.li on 2023/10/31.
//
#include "image.h"
#include "svpng.inc"

void image::output_png(const std::string &path)
{
    FILE *fp = fopen(path.c_str(), "wb");

    unsigned char *rgb, *p;
    p = rgb = new unsigned char[width * height * 3];
    unsigned col, row, r, g, b;
    for (row = 0; row < height; row++){
//            if(row % 10 == 0){
//                std::cerr << "\rScan lines remaining: " << height - row << ' ' << std::flush;
//            }
        for (col = 0; col < width; col++) {
            auto index = ((height - 1 - row) * width + col) * 3;
            r = to_output(buffer[index]);
            g = to_output(buffer[index + 1]);
            b = to_output(buffer[index + 2]);

            *p++ = (unsigned char)r;    /* R */
            *p++ = (unsigned char)g;    /* G */
            *p++ = (unsigned char)b;    /* B */
        }
    }
//        std::cout << std::endl;
    svpng(fp, width, height, rgb, 0);
    fclose(fp);
    delete []rgb;
}

void image::output_ppm(const std::string &path)
{
    FILE *fp = fopen(path.c_str(), "w");

    fprintf(fp, "P3\n%d %d\n%d\n", width, height, COLOR_SPACE_BITES-1);

    for (int row = 0; row < height; ++row) {
//            if(row % 10 == 0){
//                std::cerr << "\rScan lines remaining: " << height - row << ' ' << std::flush;
//            }
        for (int col = 0; col < width; ++col) {
            auto index = ((height - 1 - row) * width + col) * 3;
            int r = to_output(buffer[index]);
            int g = to_output(buffer[index + 1]);
            int b = to_output(buffer[index + 2]);
            fprintf(fp, "%d %d %d\n", r, g, b);
        }
    }
    fclose(fp);
}

image::~image()
{
    delete []buffer;
}

image::image(int width, int height) :
        width(width), height(height)
{
    buffer = new float[width * height * 3];
}

int image::to_output(float f) const
{
    //gamma-correct for gamma=2.0.
    f = sqrt(f);
    return static_cast<int>(COLOR_SPACE_BITES * clamp(f, 0.0, 0.999));
}